﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SegIdenPC.Entidad;
using SegIdenPC.Herramientas;
using log4net;
using GS1.Utilitario;
using System.Drawing.Imaging;
using System.Configuration;

namespace SegIdenPC.Formularios
{
    public partial class frmMantNiveles : Form
    {
        #region --- Variables y Propiedades ---
        private static readonly ILog log = LogManager.GetLogger(typeof(frmMantProducto));

        private const string TITULO = "Mantenimiento de Niveles";
        private const string FORMATO_TOTAL_ENCONTRADOS = "Total encontrados: {0}";

       

        public enum OperacionMantenimiento
        {
            Nuevo,
            Editar,
            SinCambios
        }

        private OperacionMantenimiento tipoOperacionProducto = OperacionMantenimiento.SinCambios;
        private OperacionMantenimiento tipoOperacionProductoTipo = OperacionMantenimiento.SinCambios;
        private OperacionMantenimiento tipoOperacionMaterial = OperacionMantenimiento.SinCambios;
        private OperacionMantenimiento tipoOperacionColor = OperacionMantenimiento.SinCambios;


        private enum Opcion
        {
            Grabar = 3,
            Cancelar = 4,
        }

        public NivelProducto nivelProductoActual { get; set; }
        public NivelTipo nivelTipoActual { get; set; }
        public NivelMaterial nivelMaterialActual { get; set; }
        public NivelColor nivelColorActual { get; set; }

        private Nivel niveles = null;
        #endregion

        #region --- Constructor ---
        public frmMantNiveles()
        {
            InitializeComponent();
        }
        #endregion

        #region --- Eventos Formulario ---
        private void frmMantNiveles_Load(object sender, EventArgs e)
        {
            cargarFormulario();
        }

        private void tabControl_Selecting(object sender, TabControlCancelEventArgs e)
        {
            if (!e.TabPage.Enabled) { e.Cancel = true; }
        }

        private void tbtnSalir_Click(object sender, EventArgs e)
        {
            salir();
        }

        private void frmMantNiveles_FormClosing(object sender, FormClosingEventArgs e)
        {
            finalizarFormulario();
        }

        private void dgvListadoNivelProducto_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            seleccionarNivelProducto();
        }

        private void dgvListadoNivelTipo_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            seleccionarNivelProductoTipo();
        }

        private void dgvListadoNivelMaterial_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            seleccionarNivelMaterial();
        }

        private void dgvListadoNivelColor_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            seleccionarNivelColor();
        }

        private void btnAgregarNivelProducto_Click(object sender, EventArgs e)
        {
            agregarNivelProducto();
        }

        private void btnAgregarNivelTipoProducto_Click(object sender, EventArgs e)
        {
            agregarNivelTipoProducto();
        }

        private void btnAgregarNivelMaterial_Click(object sender, EventArgs e)
        {
            agregarNivelMaterial();
        }

        private void btnAgregarNivelColor_Click(object sender, EventArgs e)
        {
            agregarNivelColor();
        }

        private void btnCopiarNivelMaterial_Click(object sender, EventArgs e)
        {
            agregarMaterialLote();
        }

        private void btnCopiarNivelColor_Click(object sender, EventArgs e)
        {
            agregarColorLote();
        }

        private void tbtnGrabar_Click(object sender, EventArgs e)
        {
            grabar();
        }

        private void tbtnCancelar_Click(object sender, EventArgs e)
        {
            //cancelar();
        }

        private void cboNivelProductoMaterial_SelectedIndexChanged(object sender, EventArgs e)
        {
            seleccionNivelMaterial();
        }

        private void cboNivelProductoTipo_SelectedIndexChanged(object sender, EventArgs e)
        {
            seleccionNivelTipoProducto();
        }

        private void cboNivelProductoColor_SelectedIndexChanged(object sender, EventArgs e)
        {
            seleccionNivelColor();
        }

        #endregion

        #region --- Metodos Propios ---
        private void cargarFormulario()
        {
            ListaGeneral listaEstadoNivelProducto = null;
            ListaGeneral listaEstadoNivelTipoProducto = null;
            ListaGeneral listaEstadoNivelMaterial = null;
            ListaGeneral listaEstadoNivelColor = null;

            try
            {
                Cursor.Current = Cursors.WaitCursor;

                // Estableciendo Ficha 0 como seleccion incial
                this.tabControl.SelectedIndex = 0;
                // Capturando evento selecting en el control Tab
              this.tabControl.Selecting += new TabControlCancelEventHandler(tabControl_Selecting);

                // Instanciando y creando listado de estado
                listaEstadoNivelProducto = new ListaGeneral();
                listaEstadoNivelProducto.Add(new General { codigo = Constantes.ESTADO_CODIGO_ACTIVO, descripcion = Constantes.ESTADO_DESCRIPCION_ACTIVO });
                listaEstadoNivelProducto.Add(new General { codigo = Constantes.ESTADO_CODIGO_INACTIVO, descripcion = Constantes.ESTADO_DESCRIPCION_INACTIVO });

                // Estableciendo datos del combo Estado Nivel Producto
                this.cboEstadoNivelProducto.DataSource = listaEstadoNivelProducto;
                this.cboEstadoNivelProducto.ValueMember = Constantes.GENERAL_CODIGO;
                this.cboEstadoNivelProducto.DisplayMember = Constantes.GENERAL_DESCRIPCION;
                this.cboEstadoNivelProducto.SelectedIndex = 0;

                // Instanciando y creando listado de estado
                listaEstadoNivelTipoProducto = new ListaGeneral();
                listaEstadoNivelTipoProducto.Add(new General { codigo = Constantes.ESTADO_CODIGO_ACTIVO, descripcion = Constantes.ESTADO_DESCRIPCION_ACTIVO });
                listaEstadoNivelTipoProducto.Add(new General { codigo = Constantes.ESTADO_CODIGO_INACTIVO, descripcion = Constantes.ESTADO_DESCRIPCION_INACTIVO });

                //Estableciendo datos del combo Estado Nivel Tipo Producto
                this.cboEstadoNivelTipoProducto.DataSource = listaEstadoNivelTipoProducto;
                this.cboEstadoNivelTipoProducto.ValueMember = Constantes.GENERAL_CODIGO;
                this.cboEstadoNivelTipoProducto.DisplayMember = Constantes.GENERAL_DESCRIPCION;
                this.cboEstadoNivelTipoProducto.SelectedIndex = 0;

                // Instanciando y creando listado de estado
                listaEstadoNivelMaterial = new ListaGeneral();
                listaEstadoNivelMaterial.Add(new General { codigo = Constantes.ESTADO_CODIGO_ACTIVO, descripcion = Constantes.ESTADO_DESCRIPCION_ACTIVO });
                listaEstadoNivelMaterial.Add(new General { codigo = Constantes.ESTADO_CODIGO_INACTIVO, descripcion = Constantes.ESTADO_DESCRIPCION_INACTIVO });

                //Estableciendo datos del combo Estado Nivel Material
                this.cboEstadoNivelMaterial.DataSource = listaEstadoNivelMaterial;
                this.cboEstadoNivelMaterial.ValueMember = Constantes.GENERAL_CODIGO;
                this.cboEstadoNivelMaterial.DisplayMember = Constantes.GENERAL_DESCRIPCION;
                this.cboEstadoNivelMaterial.SelectedIndex = 0;

                // Instanciando y creando listado de estado
                listaEstadoNivelColor = new ListaGeneral();
                listaEstadoNivelColor.Add(new General { codigo = Constantes.ESTADO_CODIGO_ACTIVO, descripcion = Constantes.ESTADO_DESCRIPCION_ACTIVO });
                listaEstadoNivelColor.Add(new General { codigo = Constantes.ESTADO_CODIGO_INACTIVO, descripcion = Constantes.ESTADO_DESCRIPCION_INACTIVO });

                //Estableciendo datos del combo Estado Nivel Color
                this.cboEstadoNivelColor.DataSource = listaEstadoNivelColor;
                this.cboEstadoNivelColor.ValueMember = Constantes.GENERAL_CODIGO;
                this.cboEstadoNivelColor.DisplayMember = Constantes.GENERAL_DESCRIPCION;
                this.cboEstadoNivelColor.SelectedIndex = 0;


                // Ejecutar carga del combo Niveles
                cargarNiveles();

                // Estableciendo focus
                this.txtNombreNivelProducto.Focus();

            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }

        private void cargarNiveles()
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            // Estableciendo operacion a ser enviada al Servicio REST
            operacion = new Operacion();
            operacion.numero = Constantes.OPERACION_LISTAR_NIVELES;

            // Instanciando y ejecutando llamada al ServicioREST
            ConexionREST conexionREST = new ConexionREST();
            contenidoXML = conexionREST.ejecutarOperacion(operacion);

            // Obteniendo Objeto de Error
            OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

            // Validar si hay error
            if (operacionError != null)
            {
                Libreria.ShowMessageboxError(operacionError.descripcion);
                return;
            }

            // Obteniendo Objeto de Nivel
            this.niveles = contenidoXML.DeserializarTo<Nivel>();

            //ListaNivelProductoTipo
            ListaNivelProducto ListaNivelProductoTipo = new ListaNivelProducto();

            foreach (NivelProducto nivelProducto in this.niveles.listaNivelProducto.lista)
            {
                ListaNivelProductoTipo.add(new NivelProducto { codigo = nivelProducto.codigo, descripcion = nivelProducto.descripcion });
            }

            // Estableciendo listado de nivel de producto
            this.cboNivelProductoTipo.DataSource = ListaNivelProductoTipo.lista;
            this.cboNivelProductoTipo.ValueMember = Constantes.GENERAL_CODIGO;
            this.cboNivelProductoTipo.DisplayMember = Constantes.GENERAL_DESCRIPCION;
            this.cboNivelProductoTipo.SelectedIndex = 0;

            //ListaNivelProductoMaterial
            ListaNivelProducto ListaNivelProductoMaterial = new ListaNivelProducto();

            foreach (NivelProducto nivelProducto in this.niveles.listaNivelProducto.lista)
            {
                ListaNivelProductoMaterial.add(new NivelProducto { codigo = nivelProducto.codigo, descripcion = nivelProducto.descripcion });
            }

            // Estableciendo listado de nivel de producto para cboNivelProductoMaterial
            this.cboNivelProductoMaterial.DataSource = ListaNivelProductoMaterial.lista;
            this.cboNivelProductoMaterial.ValueMember = Constantes.GENERAL_CODIGO;
            this.cboNivelProductoMaterial.DisplayMember = Constantes.GENERAL_DESCRIPCION;
            this.cboNivelProductoMaterial.SelectedIndex = 0;

            //ListaNivelProductoMaterialCopia
            ListaNivelProducto ListaNivelProductoMaterialCopia = new ListaNivelProducto();

            foreach (NivelProducto nivelProducto in this.niveles.listaNivelProducto.lista)
            {
                ListaNivelProductoMaterialCopia.add(new NivelProducto { codigo = nivelProducto.codigo, descripcion = nivelProducto.descripcion });
            }

            // Estableciendo listado de nivel de producto para cboNivelProductoMaterialCopia
            this.cboNivelProductoMaterialCopia.DataSource = ListaNivelProductoMaterialCopia.lista;
            this.cboNivelProductoMaterialCopia.ValueMember = Constantes.GENERAL_CODIGO;
            this.cboNivelProductoMaterialCopia.DisplayMember = Constantes.GENERAL_DESCRIPCION;
            this.cboNivelProductoMaterialCopia.SelectedIndex = 0;

            //ListaNivelProductoColor
            ListaNivelProducto ListaNivelProductoColor = new ListaNivelProducto();

            foreach (NivelProducto nivelProducto in this.niveles.listaNivelProducto.lista)
            {
                ListaNivelProductoColor.add(new NivelProducto { codigo = nivelProducto.codigo, descripcion = nivelProducto.descripcion });
            }

            // Estableciendo listado de nivel de producto para cboNivelProductoColor
            this.cboNivelProductoColor.DataSource = ListaNivelProductoColor.lista;
            this.cboNivelProductoColor.ValueMember = Constantes.GENERAL_CODIGO;
            this.cboNivelProductoColor.DisplayMember = Constantes.GENERAL_DESCRIPCION;
            this.cboNivelProductoColor.SelectedIndex = 0;

            //ListaNivelProductoColor
            ListaNivelProducto ListaNivelProductoColorCopia = new ListaNivelProducto();

            foreach (NivelProducto nivelProducto in this.niveles.listaNivelProducto.lista)
            {
                ListaNivelProductoColorCopia.add(new NivelProducto { codigo = nivelProducto.codigo, descripcion = nivelProducto.descripcion });
            }

            // Estableciendo listado de nivel de producto para cboNivelProductoColorCopia
            this.cboNivelProductoColorCopia.DataSource = ListaNivelProductoColorCopia.lista;
            this.cboNivelProductoColorCopia.ValueMember = Constantes.GENERAL_CODIGO;
            this.cboNivelProductoColorCopia.DisplayMember = Constantes.GENERAL_DESCRIPCION;
            this.cboNivelProductoColorCopia.SelectedIndex = 0;

            //Llenar grilla con datos de Producto
            seleccionNivelProducto();

            // Colorear grilla de acuerdo a criterios de Nivel Producto
            pintarGrillaNivelProducto();

            // Colorear grilla de acuerdo a criterios de Nivel Tipo Producto
            seleccionNivelTipoProducto();

            // Colorear grilla de acuerdo a criterios de Nivel Material
            seleccionNivelMaterial();

            // Colorear grilla de acuerdo a criterios de Nivel Color
            seleccionNivelColor();
        }

        private void seleccionNivelProducto()
        {
            // Se establece propiedad para evitar que genere nuevas columnas que no estan mapeadas en la grilla
            this.dgvListadoNivelProducto.AutoGenerateColumns = false;

            // Se establece la fuente de datos de la grilla
            this.dgvListadoNivelProducto.DataSource = this.niveles.listaNivelProducto.lista;
        }

        private void pintarGrillaNivelProducto()
        {
            ListPersonalizada<NivelProducto> listaNivelProducto = null;
            listaNivelProducto = (ListPersonalizada<NivelProducto>)this.dgvListadoNivelProducto.DataSource;

            if (listaNivelProducto != null)
            {
                for (int i = 0; i < listaNivelProducto.Count; i++)
                {
                    var NivelProducto = listaNivelProducto[i];

                    NivelProducto.estado = NivelProducto.estado.Equals(Constantes.ESTADO_CODIGO_INACTIVO) ? Constantes.ESTADO_DESCRIPCION_INACTIVO : Constantes.ESTADO_DESCRIPCION_ACTIVO;

                    if (NivelProducto.estado == Constantes.ESTADO_DESCRIPCION_INACTIVO)
                    {
                        this.dgvListadoNivelProducto.Rows[i].DefaultCellStyle.BackColor = Color.FromArgb(255, 128, 128);
                    }
                }
            }
        }

        private void seleccionNivelTipoProducto()
        {
            string codigoNivelProductoTipo = string.Empty;

            //se obtiene el código de Producto de tipo a escoger
            if (this.cboNivelProductoTipo.SelectedValue is string)
            {
                codigoNivelProductoTipo = this.cboNivelProductoTipo.SelectedValue.ToString();
            }
            else
            {
                return;
                //codigoNivelProductoTipo = ((NivelTipo)this.cboNivelProductoTipo.SelectedValue).codigo;
            }

            //Se ordena la lista de todos los tipos obtenidos de la lista
            List<NivelTipo> listaNivelTipo = this.niveles.listaNivelTipo.lista;

            //Se separa unicamente los tipos asociados al nivel producto
            var listaTipo = from cust in listaNivelTipo
                            where cust.codNivelProducto == codigoNivelProductoTipo
                            select cust;

            // Se establece propiedad para evitar que genere nuevas columnas que no estan mapeadas en la grilla
            this.dgvListadoNivelTipo.AutoGenerateColumns = false;

            //se asocia el resultado con la grilla de datos
            this.dgvListadoNivelTipo.DataSource = listaTipo.ToList<NivelTipo>();

            //se pinta de otro color en caso que haya uno inactivo
            for (int i = 0; i < listaTipo.ToList<NivelTipo>().Count; i++)
            {
                var NivelTipo = listaTipo.ToList<NivelTipo>()[i];

                NivelTipo.estado = NivelTipo.estado.Equals(Constantes.ESTADO_CODIGO_INACTIVO) ? Constantes.ESTADO_DESCRIPCION_INACTIVO : Constantes.ESTADO_DESCRIPCION_ACTIVO;

                if (NivelTipo.estado == Constantes.ESTADO_DESCRIPCION_INACTIVO)
                {
                    this.dgvListadoNivelTipo.Rows[i].DefaultCellStyle.BackColor = Color.FromArgb(255, 128, 128);
                }
            }
        }

        private void seleccionNivelMaterial()
        {
            string codigoNivelProductoMaterial = string.Empty;

            //se obtiene el código de Producto de tipo a escoger
            if (this.cboNivelProductoMaterial.SelectedValue is string)
            {
                codigoNivelProductoMaterial = this.cboNivelProductoMaterial.SelectedValue.ToString();
            }
            else
            {
                return;
                //codigoNivelProductoMaterial = ((NivelMaterial)this.cboNivelProductoMaterial.SelectedValue).codigo;
            }

            //Se ordena la lista de todos los materiales obtenidos de la lista
            List<NivelMaterial> listaNivelMaterial = this.niveles.listaNivelMaterial.lista;

            //Se separa unicamente los materiales asociados al nivel producto
            var listaMaterial = from cust in listaNivelMaterial
                                where cust.codNivelProducto == codigoNivelProductoMaterial
                                select cust;

            // Se establece propiedad para evitar que genere nuevas columnas que no estan mapeadas en la grilla
            this.dgvListadoNivelMaterial.AutoGenerateColumns = false;

            //se asocia el resultado con la grilla de datos
            this.dgvListadoNivelMaterial.DataSource = listaMaterial.ToList<NivelMaterial>();

            //se pinta de otro color en caso que haya uno inactivo
            for (int i = 0; i < listaMaterial.ToList<NivelMaterial>().Count; i++)
            {
                var NivelMaterial = listaMaterial.ToList<NivelMaterial>()[i];

                NivelMaterial.estado = NivelMaterial.estado.Equals(Constantes.ESTADO_CODIGO_INACTIVO) ? Constantes.ESTADO_DESCRIPCION_INACTIVO : Constantes.ESTADO_DESCRIPCION_ACTIVO;

                if (NivelMaterial.estado == Constantes.ESTADO_DESCRIPCION_INACTIVO)
                {
                    this.dgvListadoNivelMaterial.Rows[i].DefaultCellStyle.BackColor = Color.FromArgb(255, 128, 128);
                }
            }
        }

        private void seleccionNivelColor()
        {
            string codigoNivelProductoColor = string.Empty;

            //se obtiene el código de Producto de tipo a escoger
            if (this.cboNivelProductoColor.SelectedValue is string)
            {
                codigoNivelProductoColor = this.cboNivelProductoColor.SelectedValue.ToString();
            }
            else
            {
                return;
                // codigoNivelProductoColor = ((NivelMaterial)this.cboNivelProductoColor.SelectedValue).codigo;
            }

            //Se ordena la lista de todos los Colores obtenidos de la lista
            List<NivelColor> listaNivelColor = this.niveles.listaNivelColor.lista;

            //Se separa unicamente los Colores asociados al nivel producto
            var listaColor = from cust in listaNivelColor
                             where cust.codNivelProducto == codigoNivelProductoColor
                             select cust;

            // Se establece propiedad para evitar que genere nuevas columnas que no estan mapeadas en la grilla
            this.dgvListadoNivelColor.AutoGenerateColumns = false;

            //se asocia el resultado con la grilla de datos
            this.dgvListadoNivelColor.DataSource = listaColor.ToList<NivelColor>();

            //se pinta de otro color en caso que haya uno inactivo
            for (int i = 0; i < listaColor.ToList<NivelColor>().Count; i++)
            {
                var NivelMaterial = listaColor.ToList<NivelColor>()[i];

                NivelMaterial.estado = NivelMaterial.estado.Equals(Constantes.ESTADO_CODIGO_INACTIVO) ? Constantes.ESTADO_DESCRIPCION_INACTIVO : Constantes.ESTADO_DESCRIPCION_ACTIVO;

                if (NivelMaterial.estado == Constantes.ESTADO_DESCRIPCION_INACTIVO)
                {
                    this.dgvListadoNivelColor.Rows[i].DefaultCellStyle.BackColor = Color.FromArgb(255, 128, 128);
                }
            }
        }

        private void seleccionarNivelProducto()
        {
            // Valida si seleccione algun NivelProducto
            if (this.dgvListadoNivelProducto.CurrentRow != null && this.dgvListadoNivelProducto.CurrentRow.Index > -1)
            {
                // Obteniendo lista de contactos
                ListPersonalizada<NivelProducto> listaNivelProducto = (ListPersonalizada<NivelProducto>)this.dgvListadoNivelProducto.DataSource;
                NivelProducto NivelProductoActual = new NivelProducto();
                NivelProductoActual = listaNivelProducto[this.dgvListadoNivelProducto.CurrentRow.Index];

                //Cargar datos
                this.txtNombreNivelProducto.Text = NivelProductoActual.descripcion;
                this.cboEstadoNivelProducto.Text = NivelProductoActual.estado;
            }
        }

        private void seleccionarNivelProductoTipo()
        {
            // Valida si seleccione algun NivelTipo
            if (this.dgvListadoNivelTipo.CurrentRow != null && this.dgvListadoNivelTipo.CurrentRow.Index > -1)
            {
                // Obteniendo lista de contactos
                ListPersonalizada<NivelTipo> listaNivelTipo = (ListPersonalizada<NivelTipo>)this.dgvListadoNivelTipo.DataSource;
                NivelTipo NivelTipoActual = new NivelTipo();
                NivelTipoActual = listaNivelTipo[this.dgvListadoNivelTipo.CurrentRow.Index];

                //Cargar datos
                this.txtNombreNivelTipoProducto.Text = NivelTipoActual.descripcion;
                this.cboEstadoNivelTipoProducto.Text = NivelTipoActual.estado;
            }
        }

        private void seleccionarNivelMaterial()
        {
            // Valida si seleccione algun NivelMaterial
            if (this.dgvListadoNivelMaterial.CurrentRow != null && this.dgvListadoNivelMaterial.CurrentRow.Index > -1)
            {
                // Obteniendo lista de contactos
                ListPersonalizada<NivelMaterial> listaNivelMaterial = (ListPersonalizada<NivelMaterial>)this.dgvListadoNivelMaterial.DataSource;
                NivelMaterial NivelMaterialActual = new NivelMaterial();
                NivelMaterialActual = listaNivelMaterial[this.dgvListadoNivelMaterial.CurrentRow.Index];

                //Cargar datos
                this.txtNombreNivelMaterial.Text = NivelMaterialActual.descripcion;
                this.cboEstadoNivelMaterial.Text = NivelMaterialActual.estado;
            }
        }

        private void seleccionarNivelColor()
        {
            // Valida si seleccione algun NivelColor
            if (this.dgvListadoNivelColor.CurrentRow != null && this.dgvListadoNivelColor.CurrentRow.Index > -1)
            {
                // Obteniendo lista de contactos
                ListPersonalizada<NivelColor> listaNivelColor = (ListPersonalizada<NivelColor>)this.dgvListadoNivelColor.DataSource;
                NivelColor NivelColorActual = new NivelColor();
                NivelColorActual = listaNivelColor[this.dgvListadoNivelColor.CurrentRow.Index];

                //Cargar datos
                this.txtNombreNivelColor.Text = NivelColorActual.descripcion;
                this.cboEstadoNivelColor.Text = NivelColorActual.estado;
            }
        }

        private void finalizarFormulario()
        {
            this.tabControl.Selecting -= new TabControlCancelEventHandler(tabControl_Selecting);
        }

        private void salir()
        {
            this.Close();
        }

        private void agregarNivelProducto()
        {
            try
            {
                if (validarEntradaProducto()) { return; }

                // Obteniendo lista de Nivel Producto
                ListPersonalizada<NivelProducto> listaNivelProducto = (ListPersonalizada<NivelProducto>)this.dgvListadoNivelProducto.DataSource;
                if (listaNivelProducto == null) { listaNivelProducto = new ListPersonalizada<NivelProducto>(); }

                // Instanciando Nivel Producto
                NivelProducto nivelProducto = new NivelProducto();
                nivelProducto.descripcion = this.txtNombreNivelProducto.Text;
                //Se pone la descripcion (OJO CUANDO SE GRABA SE DEBE ENVIAR EL CODIGO)

                tipoOperacionProducto = OperacionMantenimiento.Nuevo;

                if (this.cboEstadoNivelProducto.SelectedValue.ToString().Equals(Constantes.ESTADO_CODIGO_INACTIVO))
                { nivelProducto.estado = Constantes.ESTADO_DESCRIPCION_INACTIVO; }
                else
                { nivelProducto.estado = Constantes.ESTADO_DESCRIPCION_NUEVO; }

                if (validarProductoRepetido(this.txtNombreNivelProducto.Text))
                {
                    //Se valida que el Tipo de Producto es Editar
                    tipoOperacionProducto = OperacionMantenimiento.Editar;

                    nivelProducto.estado = Constantes.ESTADO_DESCRIPCION_MODIFICADO;
                    ListPersonalizada<NivelProducto> listaNivelProductoNuevo = new ListPersonalizada<NivelProducto>();

                    if (listaNivelProducto != null)
                    {
                        foreach (NivelProducto item in listaNivelProducto)
                        {
                            if (item.descripcion.Equals(this.txtNombreNivelProducto.Text)) { }
                            else listaNivelProductoNuevo.Add(item);
                        }
                        listaNivelProducto = listaNivelProductoNuevo;
                    }
                }

                // Agregando NivelProducto
                listaNivelProducto.Add(nivelProducto);

                // Actualizando en grilla
                this.dgvListadoNivelProducto.DataSource = null;
                this.dgvListadoNivelProducto.DataSource = listaNivelProducto;

                // Limpiando campos del NivelProducto
                limpiarNivelProducto();

                cambiarEstadoBotones(Opcion.Grabar);
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
        }

        private void agregarNivelTipoProducto()
        {
            try
            {
                if (validarEntradaTipo()) { return; }

                // Obteniendo lista de Nivel Tipo
                ListPersonalizada<NivelTipo> listaNivelTipo = (ListPersonalizada<NivelTipo>)this.dgvListadoNivelTipo.DataSource;
                if (listaNivelTipo == null) { listaNivelTipo = new ListPersonalizada<NivelTipo>(); }

                // Instanciando Nivel Tipo
                NivelTipo nivelTipo = new NivelTipo();
                nivelTipo.descripcion = this.txtNombreNivelTipoProducto.Text;
                //Se pone la descripcion (OJO CUANDO SE GRABA SE DEBE ENVIAR EL CODIGO)

                tipoOperacionProductoTipo = OperacionMantenimiento.Nuevo;

                if (this.cboEstadoNivelTipoProducto.SelectedValue.ToString().Equals(Constantes.ESTADO_CODIGO_INACTIVO))
                { nivelTipo.estado = Constantes.ESTADO_DESCRIPCION_INACTIVO; }
                else
                { nivelTipo.estado = Constantes.ESTADO_DESCRIPCION_NUEVO; }

                if (validarTipoRepetido(this.txtNombreNivelTipoProducto.Text))
                {
                    tipoOperacionProductoTipo = OperacionMantenimiento.Editar;
                    nivelTipo.estado = Constantes.ESTADO_DESCRIPCION_MODIFICADO;

                    ListPersonalizada<NivelTipo> listaNivelTipoNuevo = new ListPersonalizada<NivelTipo>();

                    if (listaNivelTipo != null)
                    {
                        foreach (NivelTipo item in listaNivelTipo)
                        {
                            if (item.descripcion.Equals(this.txtNombreNivelTipoProducto.Text)) { }
                            else listaNivelTipoNuevo.Add(item);
                        }
                        listaNivelTipo = listaNivelTipoNuevo;
                    }
                }

                // Agregando nivelTipo
                listaNivelTipo.Add(nivelTipo);

                // Actualizando en grilla
                this.dgvListadoNivelTipo.DataSource = null;
                this.dgvListadoNivelTipo.DataSource = listaNivelTipo;

                // Limpiando campos del NivelTipo
                limpiarNivelTipo();

                cambiarEstadoBotones(Opcion.Grabar);
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
        }

        private void agregarNivelMaterial()
        {
            try
            {
                if (validarEntradaMaterial()) { return; }

                // Obteniendo lista de Nivel Material
                ListPersonalizada<NivelMaterial> listaNivelMaterial = (ListPersonalizada<NivelMaterial>)this.dgvListadoNivelMaterial.DataSource;
                if (listaNivelMaterial == null) { listaNivelMaterial = new ListPersonalizada<NivelMaterial>(); }

                // Instanciando Nivel Material
                NivelMaterial nivelMaterial = new NivelMaterial();
                nivelMaterial.descripcion = this.txtNombreNivelMaterial.Text;
                //Se pone la descripcion (OJO CUANDO SE GRABA SE DEBE ENVIAR EL CODIGO)
                //nivelMaterial.estado = this.cboEstadoNivelMaterial.SelectedValue.ToString().Equals(Constantes.ESTADO_CODIGO_INACTIVO) ? Constantes.ESTADO_DESCRIPCION_INACTIVO : Constantes.ESTADO_DESCRIPCION_ACTIVO; 
                tipoOperacionMaterial = OperacionMantenimiento.Nuevo;

                if (this.cboEstadoNivelMaterial.SelectedValue.ToString().Equals(Constantes.ESTADO_CODIGO_INACTIVO))
                {
                    nivelMaterial.estado = Constantes.ESTADO_DESCRIPCION_INACTIVO;
                }
                else
                {
                    //
                    nivelMaterial.estado = Constantes.ESTADO_DESCRIPCION_NUEVO;
                }


                if (validarMaterialRepetido(this.txtNombreNivelMaterial.Text))
                {
                    tipoOperacionMaterial = OperacionMantenimiento.Editar;
                    nivelMaterial.estado = Constantes.ESTADO_DESCRIPCION_MODIFICADO;

                    ListPersonalizada<NivelMaterial> listaNivelMaterialNuevo = new ListPersonalizada<NivelMaterial>();

                    if (listaNivelMaterial != null)
                    {
                        foreach (NivelMaterial item in listaNivelMaterial)
                        {
                            if (item.descripcion.Equals(this.txtNombreNivelMaterial.Text)) { }
                            else listaNivelMaterialNuevo.Add(item);
                        }
                        listaNivelMaterial = listaNivelMaterialNuevo;
                    }
                }

                // Agregando nivelMaterial
                listaNivelMaterial.Add(nivelMaterial);

                // Actualizando en grilla
                this.dgvListadoNivelMaterial.DataSource = null;
                this.dgvListadoNivelMaterial.DataSource = listaNivelMaterial;

                // Limpiando campos del NivelMaterial
                limpiarNivelMaterial();

                cambiarEstadoBotones(Opcion.Grabar);
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
        }

        private void agregarNivelColor()
        {
            try
            {
                if (validarEntradaColor()) { return; }

                // Obteniendo lista de Nivel Color
                ListPersonalizada<NivelColor> listaNivelColor = (ListPersonalizada<NivelColor>)this.dgvListadoNivelColor.DataSource;

                //En caso la lista esté vacía se crea una nueva
                if (listaNivelColor == null) { listaNivelColor = new ListPersonalizada<NivelColor>(); }

                // Instanciando Nivel Color
                NivelColor nivelColor = new NivelColor();
                tipoOperacionColor = OperacionMantenimiento.Nuevo;

                nivelColor.descripcion = this.txtNombreNivelColor.Text;

                //Se pone la descripcion (OJO CUANDO SE GRABA SE DEBE ENVIAR EL CODIGO)
                if (this.cboEstadoNivelColor.SelectedValue.ToString().Equals(Constantes.ESTADO_CODIGO_INACTIVO))
                {
                    nivelColor.estado = Constantes.ESTADO_DESCRIPCION_INACTIVO;
                }
                else
                {
                    nivelColor.estado = Constantes.ESTADO_DESCRIPCION_NUEVO;
                }

                //Valida si no se ha modificado el estado o ha ingresado un tipo de producto nuevo
                if (validarColorRepetido(this.txtNombreNivelColor.Text))
                {
                    //cambia de estado para facilitar el proceso de identificación
                    tipoOperacionColor = OperacionMantenimiento.Editar;
                    nivelColor.estado = Constantes.ESTADO_DESCRIPCION_MODIFICADO;
                    //Crea lista temporal
                    ListPersonalizada<NivelColor> listaNivelColorNuevo = new ListPersonalizada<NivelColor>();
                    //Crea lista nueva con la modificación
                    if (listaNivelColor != null)
                    {
                        foreach (NivelColor item in listaNivelColor)
                        {
                            if (item.descripcion.Equals(this.txtNombreNivelColor.Text)) { }
                            else listaNivelColorNuevo.Add(item);
                        }
                        listaNivelColor = listaNivelColorNuevo;
                    }
                }

                // Agregando nivelMaterial
                listaNivelColor.Add(nivelColor);

                // Actualizando en grilla
                this.dgvListadoNivelColor.DataSource = null;
                this.dgvListadoNivelColor.DataSource = listaNivelColor;

                // Limpiando campos del NivelMaterial
                limpiarNivelColor();

                cambiarEstadoBotones(Opcion.Grabar);
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
        }

        private bool validarProductoRepetido(string NombreNivelProducto)
        {
            bool resultado = false;

            // Obteniendo lista de NivelProducto
            ListPersonalizada<NivelProducto> listaNivelProducto = (ListPersonalizada<NivelProducto>)this.dgvListadoNivelProducto.DataSource;

            if (listaNivelProducto != null)
            {
                foreach (NivelProducto item in listaNivelProducto)
                {
                    if (item.descripcion.Equals(NombreNivelProducto))
                    {
                        resultado = true;
                        break;
                    }
                }
            }

            return resultado;
        }

        private bool validarTipoRepetido(string NombreNivelTipo)
        {
            bool resultado = false;

            // Obteniendo lista de NivelProducto
            ListPersonalizada<NivelTipo> listaNivelTipo = (ListPersonalizada<NivelTipo>)this.dgvListadoNivelTipo.DataSource;

            if (listaNivelTipo != null)
            {
                foreach (NivelTipo item in listaNivelTipo)
                {
                    if (item.descripcion.Equals(NombreNivelTipo))
                    {
                        resultado = true;
                        break;
                    }
                }
            }
            return resultado;
        }

        private bool validarMaterialRepetido(string NombreMaterial)
        {
            bool resultado = false;

            // Obteniendo lista de NivelProducto
            ListPersonalizada<NivelMaterial> listaNivelMaterial = (ListPersonalizada<NivelMaterial>)this.dgvListadoNivelMaterial.DataSource;

            if (listaNivelMaterial != null)
            {
                foreach (NivelMaterial item in listaNivelMaterial)
                {
                    if (item.descripcion.Equals(NombreMaterial))
                    {
                        resultado = true;
                        break;
                    }
                }
            }
            return resultado;
        }

        private bool validarColorRepetido(string NombreColor)
        {
            bool resultado = false;

            // Obteniendo lista de NivelProducto
            ListPersonalizada<NivelColor> listaNivelColor = (ListPersonalizada<NivelColor>)this.dgvListadoNivelColor.DataSource;

            if (listaNivelColor != null)
            {
                foreach (NivelColor item in listaNivelColor)
                {
                    if (item.descripcion.Equals(NombreColor))
                    {
                        resultado = true;
                        break;
                    }
                }
            }
            return resultado;
        }

        private bool validarEntradaProducto()
        {
            bool resultado = false;

            this.txtNombreNivelProducto.Text = this.txtNombreNivelProducto.Text.Trim();

            if (this.txtNombreNivelProducto.Text.Equals(string.Empty))
            {
                Libreria.CampoNecesario(this.txtNombreNivelProducto, "Debe ingresar el campo Nombre Nivel de Producto", TITULO);
                return true;
            }

            if (tipoOperacionProducto.Equals(OperacionMantenimiento.Nuevo))
            {
                Libreria.CampoNecesario(this.txtNombreNivelProducto, "Tiene que grabar primero antes de ingresar un Nivel de Producto", TITULO);
                return true;
            }
            return resultado;
        }

        private bool validarEntradaTipo()
        {
            bool resultado = false;

            this.txtNombreNivelTipoProducto.Text = this.txtNombreNivelTipoProducto.Text.Trim();

            if (this.txtNombreNivelTipoProducto.Text.Equals(string.Empty))
            {
                Libreria.CampoNecesario(this.txtNombreNivelTipoProducto, "Debe ingresar el campo Nombre Nivel de Tipo Producto", TITULO);
                return true;
            }
            return resultado;
        }

        private bool validarEntradaMaterial()
        {
            bool resultado = false;

            this.txtNombreNivelMaterial.Text = this.txtNombreNivelMaterial.Text.Trim();

            if (this.txtNombreNivelMaterial.Text.Equals(string.Empty))
            {
                Libreria.CampoNecesario(this.txtNombreNivelMaterial, "Debe ingresar el campo Nombre Nivel de Material", TITULO);
                return true;
            }
            return resultado;
        }

        private bool validarEntradaColor()
        {
            bool resultado = false;

            this.txtNombreNivelColor.Text = this.txtNombreNivelColor.Text.Trim();

            if (this.txtNombreNivelColor.Text.Equals(string.Empty))
            {
                Libreria.CampoNecesario(this.txtNombreNivelColor, "Debe ingresar el campo Nombre Color", TITULO);
                return true;
            }
            return resultado;
        }

        private void limpiarNivelProducto()
        {
            this.txtNombreNivelProducto.Text = string.Empty;
            this.cboEstadoNivelProducto.Text = Constantes.ESTADO_CODIGO_ACTIVO;
        }

        private void limpiarNivelTipo()
        {
            this.txtNombreNivelTipoProducto.Text = string.Empty;
            this.cboEstadoNivelTipoProducto.Text = Constantes.ESTADO_CODIGO_ACTIVO;
        }

        private void limpiarNivelMaterial()
        {
            this.txtNombreNivelMaterial.Text = string.Empty;
            this.cboEstadoNivelMaterial.Text = Constantes.ESTADO_CODIGO_ACTIVO;
            this.cboNivelProductoMaterial.Text = Constantes.VALOR_UNO;
        }

        private void limpiarNivelColor()
        {
            this.txtNombreNivelColor.Text = string.Empty;
            this.cboEstadoNivelColor.Text = Constantes.ESTADO_CODIGO_ACTIVO;
            this.cboNivelProductoColor.Text = Constantes.VALOR_UNO;
        }

        private void cambiarEstadoBotones(Opcion tipoOpcion)
        {
            switch (tipoOpcion)
            {
                case Opcion.Grabar:
                    this.tbtnCancelar.Enabled = true;
                    this.tbtnGrabar.Enabled = true;
                    break;
                case Opcion.Cancelar:
                    this.tbtnCancelar.Enabled = false;
                    this.tbtnGrabar.Enabled = false;
                    break;
            }
        }

        private void agregarMaterialLote()
        {
            string codigoNivelProductoMaterialCopia = string.Empty;

            //se obtiene el código de Producto de tipo a escoger
            if (this.cboNivelProductoMaterialCopia.SelectedValue is string)
            {
                codigoNivelProductoMaterialCopia = this.cboNivelProductoMaterialCopia.SelectedValue.ToString();
            }
            else
            {
                codigoNivelProductoMaterialCopia = ((NivelMaterial)this.cboNivelProductoMaterialCopia.SelectedValue).codigo;
            }

            //Se ordena la lista de todos los materiales obtenidos de la lista
            List<NivelMaterial> listaNivelMaterial = this.niveles.listaNivelMaterial.lista;

            //Se separa unicamente los materiales asociados al nivel producto
            var listaMaterialCopia = from cust in listaNivelMaterial
                                     where cust.codNivelProducto == codigoNivelProductoMaterialCopia
                                     select cust;

            //Se carga la lista de los materiales que existen actualmente en una lista temporal
            ListPersonalizada<NivelMaterial> listaNivelMaterialActual = (ListPersonalizada<NivelMaterial>)this.dgvListadoNivelMaterial.DataSource;

            //Se copia todos los materiales exceptuando los que ya existen en la lista temporal
            //Se lee cada uno de los objetos de  la lista a copiar
            foreach (NivelMaterial nivelMaterial in listaMaterialCopia.ToList<NivelMaterial>())
            {
                // se valida cada material. En caso no este en la lista
                if (!validarMaterialRepetido(nivelMaterial.descripcion))
                {
                    //si no está, se carga en  la lista temporal
                    listaNivelMaterialActual.Add(new NivelMaterial { descripcion = nivelMaterial.descripcion, estado = Constantes.ESTADO_DESCRIPCION_NUEVO });
                    //Con un ingreso se confirma el ingreso de nuevos materiales
                    tipoOperacionMaterial = OperacionMantenimiento.Nuevo;
                }
            }
            this.dgvListadoNivelMaterial.DataSource = null;
            this.dgvListadoNivelMaterial.DataSource = listaNivelMaterialActual;
        }

        private void agregarColorLote()
        {
            string codigoNivelProductoColorCopia = string.Empty;

            //se obtiene el código de Producto de tipo a escoger
            if (this.cboNivelProductoColorCopia.SelectedValue is string)
            {
                codigoNivelProductoColorCopia = this.cboNivelProductoColorCopia.SelectedValue.ToString();
            }
            else
            {
                codigoNivelProductoColorCopia = ((NivelColor)this.cboNivelProductoColorCopia.SelectedValue).codigo;
            }

            //Se ordena la lista de todos los Colores obtenidos de la lista
            List<NivelColor> listaNivelColor = this.niveles.listaNivelColor.lista;

            //Se separa unicamente los Colores asociados al nivel producto
            var listaColorCopia = from cust in listaNivelColor
                                  where cust.codNivelProducto == codigoNivelProductoColorCopia
                                  select cust;

            //Se carga la lista de los Colores que existen actualmente en una lista temporal
            ListPersonalizada<NivelColor> listaNivelColorActual = (ListPersonalizada<NivelColor>)this.dgvListadoNivelColor.DataSource;

            //Se copia todos los Colores exceptuando los que ya existen en la lista temporal
            //Se lee cada uno de los objetos de  la lista a copiar
            foreach (NivelColor nivelColor in listaColorCopia.ToList<NivelColor>())
            {
                // se valida cada Color. En caso no este en la lista
                if (!validarColorRepetido(nivelColor.descripcion))
                {
                    //si no está, se carga en  la lista temporal
                    listaNivelColorActual.Add(new NivelColor { descripcion = nivelColor.descripcion, estado = Constantes.ESTADO_DESCRIPCION_NUEVO });
                    //Con un ingreso se confirma el ingreso de nuevos Colores
                    tipoOperacionColor = OperacionMantenimiento.Nuevo;
                }
            }
            this.dgvListadoNivelColor.DataSource = null;
            this.dgvListadoNivelColor.DataSource = listaNivelColorActual;
        }

        private void grabar()
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            if (tipoOperacionProducto.Equals(OperacionMantenimiento.Nuevo))
            {
                // Solicitar confirmacion
                if (!Libreria.ShowMessageboxPregunta(("¿Estas seguro de registrar el tipo de producto?"), TITULO)) { return; }
                // Estableciendo operacion a ser enviada al Servicio REST

                operacion = new Operacion();
                operacion.numero = Constantes.OPERACION_REGISTRAR_NIVEL_PRODUCTO;
                operacion.nivelProducto = new NivelProducto();
                operacion.nivelProducto.descripcion = this.txtNombreNivelProducto.Text;
                operacion.nivelProducto.estado = this.cboEstadoNivelProducto.SelectedValue.ToString();


            }
            else if (tipoOperacionProducto.Equals(OperacionMantenimiento.Editar))
            {
            }
            else if (tipoOperacionProducto.Equals(OperacionMantenimiento.SinCambios))
            {
                if (tipoOperacionProductoTipo.Equals(OperacionMantenimiento.Nuevo))
                {
                }
                if (tipoOperacionProductoTipo.Equals(OperacionMantenimiento.Editar))
                {
                }
                if (tipoOperacionMaterial.Equals(OperacionMantenimiento.Nuevo))
                {
                }
                if (tipoOperacionMaterial.Equals(OperacionMantenimiento.Editar))
                {
                }
                if (tipoOperacionColor.Equals(OperacionMantenimiento.Nuevo))
                {
                }
                if (tipoOperacionColor.Equals(OperacionMantenimiento.Editar))
                {
                }
            }

            // Ejecutar la carga de datos nuevamente
            cargarNiveles();

            //pone todos los indicadores en Sin cambios nuevamente

            tipoOperacionProducto = OperacionMantenimiento.SinCambios;
            tipoOperacionProductoTipo = OperacionMantenimiento.SinCambios;
            tipoOperacionMaterial = OperacionMantenimiento.SinCambios;
            tipoOperacionColor = OperacionMantenimiento.SinCambios;
        }
        #endregion
    }
}